#include "AudioOutput.h"

AudioOutput::AudioOutput(const SDL_AudioSpec &audio_params, AVFrameQueue *frame_queue)
    : src_target_(audio_params), frame_queue_(frame_queue), 
      audio_stream_(nullptr), audio_device_(0), running_(false) {
}

AudioOutput::~AudioOutput() {
    DeInit();
}

int AudioOutput::Init() {
    // 初始化SDL音频子系统
    if (!SDL_Init(SDL_INIT_AUDIO)) {
        av_log(NULL, AV_LOG_ERROR, "SDL_Init failed: %s\n", SDL_GetError());
        return -1;
    }

    // 检查可用音频设备
    int num_devices = SDL_GetNumAudioDrivers();
    if (num_devices <= 0) {
        av_log(NULL, AV_LOG_ERROR, "No audio devices available\n");
        SDL_Quit();
        return -1;
    }

    // 设置灵活的音频参数
    SDL_AudioSpec desired = src_target_;
    SDL_AudioSpec obtained;

    // 允许格式转换
    desired.format = SDL_AUDIO_F32; // 首选32位浮点

    // 尝试打开设备
    audio_device_ = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
                                       &desired);
    if (audio_device_ == 0) {
        av_log(NULL, AV_LOG_ERROR, "Couldn't open audio: %s\n", SDL_GetError());
        SDL_Quit();
        return -1;
    }
    // 设置目标音频格式
    dst_target_.freq = src_target_.freq; // 采样率
    dst_target_.channels = src_target_.channels; // 声道数
    dst_target_.format = SDL_AUDIO_F32; // SDL3推荐使用浮点格式

    // 创建音频流(用于格式转换)
    audio_stream_ = SDL_CreateAudioStream(&src_target_, &dst_target_);
    if (!audio_stream_) {
        av_log(NULL, AV_LOG_ERROR, "Failed to create audio stream: %s\n", SDL_GetError());
        SDL_Quit();
        return -1;
    }

    // 打开默认音频设备
    audio_device_ = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &src_target_);
    if (audio_device_ == 0) {
        av_log(NULL, AV_LOG_ERROR, "Failed to open audio device: %s\n", SDL_GetError());
        SDL_DestroyAudioStream(audio_stream_);
        SDL_Quit();
        return -1;
    }

    // 绑定音频流到设备
    if (!SDL_BindAudioStream(audio_device_, audio_stream_)) {
        av_log(NULL, AV_LOG_ERROR, "Failed to bind audio stream: %s\n", SDL_GetError());
        SDL_DestroyAudioStream(audio_stream_);
        SDL_CloseAudioDevice(audio_device_);
        SDL_Quit();
        return -1;
    }

    // 开始播放
    SDL_ResumeAudioDevice(audio_device_);

    return 0;
}

int AudioOutput::DeInit() {
    running_ = false;
    
    // 等待播放线程结束
    if (play_thread_.joinable()) {
        play_thread_.join();
    }

    // 解绑并销毁音频流
    if (audio_stream_) {
        SDL_UnbindAudioStream(audio_stream_);
        SDL_DestroyAudioStream(audio_stream_);
        audio_stream_ = nullptr;
    }

    // 关闭音频设备
    if (audio_device_ != 0) {
        SDL_CloseAudioDevice(audio_device_);
        audio_device_ = 0;
    }

    // 退出SDL子系统
    SDL_QuitSubSystem(SDL_INIT_AUDIO);
    return 0;
}

void AudioOutput::StartPlay() {
    running_ = true;
    play_thread_ = std::thread(&AudioOutput::PlayAudio, this);
}

void AudioOutput::PlayAudio() {
    while (running_) {
        AVFrame *frame = frame_queue_->Pop(10);
        if (!frame) {
            continue;
        }

        // 检查音频流状态
        // if (SDL_GetAudioStreamStatus(audio_stream_) == SDL_AUDIOSTREAM_ERROR) {
        //     av_log(NULL, AV_LOG_ERROR, "Audio stream error\n");
        //     break;
        // }

        // 计算音频数据大小
        int data_size = av_samples_get_buffer_size(
            nullptr, frame->ch_layout.nb_channels, 
            frame->nb_samples, (AVSampleFormat)frame->format, 1);

        // 写入音频数据到流
        if (!SDL_PutAudioStreamData(audio_stream_, frame->data[0], data_size)) {
            av_log(NULL, AV_LOG_ERROR, "Failed to put audio data: %s\n", SDL_GetError());
        }

        // 等待音频流有足够空间(避免缓冲区溢出)
        while (SDL_GetAudioStreamAvailable(audio_stream_) > MAX_AUDIO_BUFFER_SIZE && running_) {
            SDL_Delay(10);
        }

        av_frame_free(&frame);
    }
}